package com.ty.paypal.service.order.capture;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.paypal.http.HttpResponse;
import com.paypal.http.exceptions.HttpException;
import com.paypal.orders.AddressPortable;
import com.paypal.orders.AmountBreakdown;
import com.paypal.orders.AmountWithBreakdown;
import com.paypal.orders.ApplicationContext;
import com.paypal.orders.Item;
import com.paypal.orders.LinkDescription;
import com.paypal.orders.Money;
import com.paypal.orders.Name;
import com.paypal.orders.Order;
import com.paypal.orders.OrderRequest;
import com.paypal.orders.OrdersCreateRequest;
import com.paypal.orders.PurchaseUnitRequest;
import com.paypal.orders.ShippingDetail;
import com.ty.paypal.service.PayPalClient;

/*
*
*1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
*This step extends the SDK client. It's not mandatory to extend the client, you can also inject it.
*/
public class CreateOrder extends PayPalClient {
  //2. Set up your server to receive a call from the client
  /**
   *Method to create order
   *
   *@param debug true = print response data
   *@return HttpResponse<Order> response received from API
   *@throws IOException Exceptions from API if any
   */
  public HttpResponse<Order> createOrder(boolean debug) throws IOException {
    OrdersCreateRequest request = new OrdersCreateRequest();
    request.prefer("return=representation");
    request.requestBody(buildMyRequestBody());
//    request.requestBody(buildRequestBody());
    //3. Call PayPal to set up a transaction
    HttpResponse<Order> response = client().execute(request);
    if (debug) {
      if (response.statusCode() == 201) {
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Status: " + response.result().status());
        System.out.println("Order ID: " + response.result().id());
        System.out.println("Intent: " + response.result().checkoutPaymentIntent());
        System.out.println("Links: ");
        for (LinkDescription link : response.result().links()) {
          System.out.println("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());
        }
        System.out.println("Total Amount: " + response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode()
            + " " + response.result().purchaseUnits().get(0).amountWithBreakdown().value());
      }
    }
    return response;
  }

  /**
   * 
   *创建我的订单
   *@return OrderRequest with created order request
   */
  private OrderRequest buildMyRequestBody() {
    OrderRequest orderRequest = new OrderRequest();
    orderRequest.checkoutPaymentIntent("CAPTURE"); //创建订单类型 1.CAPTURE 立即付款 2.AUTHORIZE 授权

  //brandName 付款业务标签 landingPage 显示账单以供客户结账的登录页的类型
    ApplicationContext applicationContext = new ApplicationContext().brandName("共享服务");
    orderRequest.applicationContext(applicationContext);

    List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<PurchaseUnitRequest>();
    PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest().referenceId("PUHF") //referenceId 多个购买使用 PUHF 单个使用默认值
        .description("充电12小时套餐").customId("100026").softDescriptor("使用共享服务充电12小时套餐，收费$2.10")//description 订单的描述信息、 customId 客户id、softDescriptor 客户信用卡上对付款描述
        .amountWithBreakdown(new AmountWithBreakdown().currencyCode("USD").value("2.10")//使用美元支付以及 应付款项
        		//子项信息 对这应付款项的解释
            .amountBreakdown(new AmountBreakdown().itemTotal(new Money().currencyCode("USD").value("2.00"))//商品总价
                .handling(new Money().currencyCode("USD").value("0.10"))//手续费
//                .taxTotal(new Money().currencyCode("USD").value("0.20"))//税收
                ));
    purchaseUnitRequests.add(purchaseUnitRequest);
    orderRequest.purchaseUnits(purchaseUnitRequests);
    return orderRequest;
  }
  
  /**
   * 示例
   * @return
   */
  private OrderRequest buildRequestBody() {
	  OrderRequest orderRequest = new OrderRequest();
	  orderRequest.checkoutPaymentIntent("CAPTURE"); //创建订单类型 1.CAPTURE 立即付款 2.AUTHORIZE 授权
	  
	  //brandName 付款业务标签 landingPage 显示账单以供客户结账的登录页的类型
	  ApplicationContext applicationContext = new ApplicationContext().brandName("EXAMPLE INC").landingPage("BILLING")
	   .shippingPreference("SET_PROVIDED_ADDRESS"); //显示收货地址 - 允许修改收货地址
	  orderRequest.applicationContext(applicationContext);
	  
	  List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<PurchaseUnitRequest>();
	  PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest().referenceId("PUHF") //referenceId 多个购买使用 PUHF 单个使用默认值
			  .description("Sporting Goods").customId("CUST-HighFashions").softDescriptor("HighFashions")//description 订单的描述信息、 customId 客户id、softDescriptor 客户信用卡上对付款描述
			  .amountWithBreakdown(new AmountWithBreakdown().currencyCode("USD").value("230.00")//使用美元支付以及 应付款项
					  //子项信息 对这应付款项的解释
					  .amountBreakdown(new AmountBreakdown().itemTotal(new Money().currencyCode("USD").value("180.00"))//商品总价
							  .shipping(new Money().currencyCode("USD").value("30.00"))//快递费
							  .handling(new Money().currencyCode("USD").value("10.00"))//手续费
							  .taxTotal(new Money().currencyCode("USD").value("20.00"))//税收
							  .shippingDiscount(new Money().currencyCode("USD").value("10.00"))))//运费折扣
			  .items(new ArrayList<Item>() {
				  //商品详情 商品名称、描述、物品号、价格、税收、类别
				  {
					  add(new Item().name("T-shirt").description("Green XL").sku("sku01")
							  .unitAmount(new Money().currencyCode("USD").value("90.00"))
							  .tax(new Money().currencyCode("USD").value("10.00")).quantity("1")
							  .category("PHYSICAL_GOODS"));
					  add(new Item().name("Shoes").description("Running, Size 10.5").sku("sku02")
							  .unitAmount(new Money().currencyCode("USD").value("45.00"))
							  .tax(new Money().currencyCode("USD").value("5.00")).quantity("2")
							  .category("PHYSICAL_GOODS"));
				  }
			  })
			  //地址信息
			  .shippingDetail(new ShippingDetail().name(new Name().fullName("John Doe"))
					  .addressPortable(new AddressPortable().addressLine1("123 Townsend St").addressLine2("Floor 6")
							  .adminArea2("San Francisco").adminArea1("CA").postalCode("94107").countryCode("US")));
	  purchaseUnitRequests.add(purchaseUnitRequest);
	  orderRequest.purchaseUnits(purchaseUnitRequests);
	  return orderRequest;
  }

  /**
   *This driver function invokes the createOrder function to create
   *a sample order.
   */
  public static void main(String args[]) {
	// 同时支持代理 HTTP/HTTPS 请求
	  System.setProperty("proxyHost","127.0.0.1");
	  System.setProperty("proxyPort","1080");
    try {
      new CreateOrder().createOrder(true);
//    	new CreateOrder().getToken();
//    	new CreateOrder().createProduct();
    } catch (HttpException e) {
      System.out.println(e.getLocalizedMessage());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
